home *** CD-ROM | disk | FTP | other *** search
Text File | 1992-01-23 | 45.0 KB | 1,831 lines |
- [ This device driver for the SunOS kernel allows the kernel network
- layer to send IP packet inside AX25 (using a TNC on a serial port),
- exactly like KA9Q NOS does.
- The AX25 device appears exactly (ok, minus possible bugs :-) like
- any other network device does to the kernel, so you can use any old
- regular SunOS TCP/IP programs (ftp, telnet, etc). (Tested on Sun3/60
- and Sun4/260, SunOS4.1.1.)
- VERSION 1.0 deraadt@lego.cuc.ab.ca ]
-
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then unpack
- # it by saving it into a file and typing "sh file". To overwrite existing
- # files, type "sh file -c". You can also feed this as standard input via
- # unshar, or by typing "sh <file", e.g.. If this archive is complete, you
- # will see the following message at the end:
- # "End of shell archive."
- # Contents: Makefile README ax25.8 ax25.c ax25ether.c if_ax.h tty_ax.c
- # Wrapped by deraadt@cpsc.UCalgary.CA on Sat Jan 25 02:48:06 1992
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f 'Makefile' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'Makefile'\"
- else
- echo shar: Extracting \"'Makefile'\" \(73 characters\)
- sed "s/^X//" >'Makefile' <<'END_OF_FILE'
- XCFLAGS= -g
- XBIN= ax25ether ax25
- X
- Xall: $(BIN)
- X
- Xclean:
- X $(RM) *.o *~ $(BIN)
- END_OF_FILE
- if test 73 -ne `wc -c <'Makefile'`; then
- echo shar: \"'Makefile'\" unpacked with wrong size!
- fi
- # end of 'Makefile'
- fi
- if test -f 'README' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'README'\"
- else
- echo shar: Extracting \"'README'\" \(3792 characters\)
- sed "s/^X//" >'README' <<'END_OF_FILE'
- XSTATUS:
- XTested on a Sun3/60 and a Sun4/260 running SunOS4.1.1, using a PacComm
- XTiny-2 TNC, and talking with other NOS sites in Calgary, Alberta.
- X
- XINSTALL:
- X0. Substitute the name 'KERNEL_CONFIG_FILE' in the following steps with the
- X kernel configuration file for your new kernel (If in doubt, make a copy
- X of GENERIC, and use it).
- X Also, substitute 'sun3' with whatever the command 'arch -k' says
- X your kernel architecture is.
- X
- X1. First, you need to add the device driver to the kernel. Add this line to
- X /usr/sys/sun3/conf/KERNEL_CONFIG_FILE.
- X pseudo-device ax1 init ax_attach
- X ^ this number determines how many TNCs you can hook up.
- X
- X2. splice these sections in the appropriate (fairly obvious) places in
- X /usr/sys/sun/str_conf.c
- X #include "ax.h"
- X
- X #if NAX > 0
- X extern struct streamtab axinfo;
- X #endif
- X
- X #if NAX > 0
- X { "ax25", &axinfo },
- X #endif
- X
- X3. add this line to /usr/sys/conf.common/files.cmn
- X os/tty_ax.c optional ax
- X
- X4. Install the needed files in the kernel sys tree
- X # cp tty_ax.c /usr/sys/os
- X # cp if_ax.h /usr/include/sys
- X # cp if_ax.h /usr/sys/sys
- X
- X5. Build the kernel
- X # cd /usr/sys/sun3/conf
- X # config KERNEL_CONFIG_FILE
- X # cd ../KERNEL_CONFIG_FILE
- X # make
- X # mv /vmunix /vmunix.save
- X # cp vmunix /vmunix
- X
- X6. Reboot your machine to start up the new kernel.
- X
- X7. Now, build the two user level programs: ax25ether and ax25, and give
- X it a try.
- X # make
- X
- X8. Put your hostname in /etc/hosts with the correct IP address.
- X 44.135.145.28 ve6uug-0
- X
- X9. Ensure that the netmask for network #44 is correct. Ussually it should
- X be 0xffffff00. Put that in /etc/netmasks, like this.
- X 44 255.255.255.0
- X (If you are running YP, you may need to rebuild the databases.
- X # (cd /var/yp; make)
- X )
- X
- X10. Ensure your TNC is in KISS mode, with the proper KISS timing parameters
- X already set. Now we can start up the interface.
- X
- X # ./ax25 -v ve6uug-0 ve6uug-0 /dev/ttyb
- X popping module: ttcompat
- X popping module: ldterm
- X pushing module: ax25
- X network device: ax0
- X addresses: ax25 ac.8a.6c.aa.aa.8e.60 'VE6UUG-0' = ether 99:da:55:b5:d6:70
- X execute: ifconfig ax0 ve6uug-0 netmask + broadcast + up
- X Setting netmask of ax0 to 255.255.255.0
- X
- X The first instance of your callsign is resolved according to /etc/hosts
- X to generate an IP address. The second instance of your callsign determines
- X what your AX25 hardware address is, which is what other parties use to
- X actually send a packet to your hardware.
- X
- X11. Check to see if the interface has come up.
- X # netstat -in
- X Name Mtu Net/Dest Address Ipkts Ierrs Opkts Oerrs Collis Queue
- X le0 1500 136.159.222.0 136.159.222.1 3871 0 1847 0 0 0
- X lo0 1536 127.0.0.0 127.0.0.1 339 0 339 0 0 0
- X ax0 1000 44.135.145.0 44.135.145.28 0 0 0 0 0 0
- X
- X12. Try to talk to a few other hosts, ie. telnet, finger, etc.
- X
- XBUGS:
- XGenerally, etherfind seems to work, but only on the second and successive
- Xattempts. The first attempt fails with an NIOCBIND error. No idea why.
- X
- XPackets with digipeater addresses in their header are dropped on the floor
- Ximmediately. Proper digipeater support cannot be easily added. (My opinion:
- Xdigipeating is a dumb idea).
- X
- XDTR behaviour: M_HANGUP and M_UNHANGUP streams messages are not handled
- Xcorrectly. Currently, it's best to <snip> your TNC's DTR line.
- X
- XOTHER NOTES:
- XThe kernel ARP routines can only deal with 6 byte ethernet addresses. A
- Xbizzare encoding scheme is used to encode AX25 7-byte addresses into these
- X6-byte addresses. When AX25 addresses are converted, the resulting ethernet
- Xaddresses always have their upper byte set to 0x99. The program ax25ether
- Xwill convert between AX25 addresses and ethernet addresses as shown using
- Xthe arp command.
- END_OF_FILE
- if test 3792 -ne `wc -c <'README'`; then
- echo shar: \"'README'\" unpacked with wrong size!
- fi
- # end of 'README'
- fi
- if test -f 'ax25.8' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'ax25.8'\"
- else
- echo shar: Extracting \"'ax25.8'\" \(3814 characters\)
- sed "s/^X//" >'ax25.8' <<'END_OF_FILE'
- X.\" manual page v0.1 for ax25 pl-0
- X.\" SH section heading
- X.\" SS subsection heading
- X.\" LP paragraph
- X.\" IP indented paragraph
- X.\" TP hanging label
- X.TH AX25 8
- X.SH NAME
- Xax25 \- AX25/IP ifconfig Utility
- X.SH SYNOPSIS
- X.B ax25
- X[
- X.I \-v
- X]
- X.I <network address>
- X.I <ham call sign>
- X.I <tty_name>
- X.SH DESCRIPTION
- X.LP
- XAmateur packet radio enthusiasts nowadays send IP packets over radio
- Xlinks. Hanging off a serial port on their computer, TNC modems are
- Xused to provide CSMA-like behaviour so that the single radio channel
- Xcan be shared between multiple stations (somewhat like how ethernet
- Xworks). Packet radio is a broadcast medium, hence the TNC is
- Xresponsible for sharing the bandwidth with other TNC's. The computer
- Xtalking to the TNC must use a protocol called KISS (a simple
- Xderivative of SLIP encoding) to send/receive packets to/from the TNC.
- X.LP
- XAX25 packets vary in length. The packet header at the start of the
- Xpacket has four parts:
- X.TP
- X1.
- XA (guaranteed to be) unique source address.
- X.TP
- X2.
- XA destination addresses.
- X.TP
- X3.
- XAn AX25 packet type field. In our case it is always set to
- XUI, to indicate that this is an AX25 datagram.
- X.TP
- X4.
- XA small number, choosing between various higher level
- Xprotocols, called the protocol ID.
- X.LP
- XThe addresses found in the header are a simple 7-byte encoding of the
- XHAM radio call sign and substation ID. These addresses are used just
- Xlike ethernet hardware addresses are, to provide a unique name for
- Xeach station. The protocol ID can choose between many protocols but
- Xusers of IP-over-AX25 under Unix are really only concerned with two
- XAX25 sub-protocols: ARP and IP.
- X.LP
- XAX25 packets (received via KISS encoding from the TNC) which are found
- Xto contain ARP or IP datagrams are decoded and handed off to the
- Xkernel networking code. Similarily, the network code gives outbound
- Xdatagrams to the AX25 device driver, where the reverse process occurs:
- Xthey are encapsulated in AX25 packets and, after KISS encoding, sent
- Xoff to the TNC for transmission.
- X.LP
- XBoth incoming and outgoing ARP datagrams require special handling.
- XThe Unix kernel's internal ARP cache contains translations between
- X4-byte IP addresses and 6-byte ethernet addresses. It's convenient to
- Xnot rewrite the kernel's ARP implementation, so an encoding scheme was
- Xdeveloped which converts 7-byte AX25 addresses to/from 6-byte ethernet
- Xaddresses. This is too twisted to describe here, so refer to the
- Xdevice driver source.
- X.LP
- X.SH OPTIONS
- XYou must be root to run this. It's a good idea to start it from
- X/etc/rc.local in the background.
- X.TP
- X.B \-v
- XPrint out more information while setting up the link.
- X.TP
- X.B <network address>
- XThis provides the IP address for the network port. This name gets passed
- Xto ifconfig(8), so it can be a name out of the hosts(5) database.
- X.TP
- X.B <ham call sign>
- XThis is your HAM call sign, with your substation ID.
- X.TP
- X.B <tty_name>
- XCommunicate over the named device at 9600 baud.
- X.LP
- X.SH EXAMPLE
- X.IP
- Xax25 44.135.145.28 ve6uug-0 /dev/ttyb
- X\".SH FILES
- X.SH SEE ALSO
- XMike Chepponis (K3MC), Phil Karn (KA9Q).
- X.I The KISS TNC: A simple Host\-to\-TNC communications protocol.
- X.LP
- XPacComm.
- X.I Operating Manual for PacComm Packet Controllers, pg. 31.
- X.TP
- X.B RFC1055
- XRomkey, J.
- X.I A Nonstandard for Transmission of IP Datagrams Over Serial Lines: SLIP
- X.LP
- XThe README file supplied with this AX25 package.
- X.LP
- X\".SH DIAGNOSTICS
- X\".SH NOTES
- X.SH BUGS
- XEtherfind doesn't work as expected the first time you run it!
- X.LP
- XTNC's that toggle DTR for each packet can cause problems because
- Xstreams M_HANGUP and M_UNHANGUP messages are treated incorrectly. If
- Xyou see console messages about M_HANGUP and M_UNHANGUP, cutting the
- XDTR line will solve the problem.
- X.LP
- X.SH AUTHORS
- XTheo de Raadt \<deraadt\@lego.cuc.ab.ca\> [kernel hack]
- X.LP
- XWilliam Graham (VE6UUG) \<uug\@indigo.cuc.ab.ca\> [HAM]
- X.LP
- END_OF_FILE
- if test 3814 -ne `wc -c <'ax25.8'`; then
- echo shar: \"'ax25.8'\" unpacked with wrong size!
- fi
- # end of 'ax25.8'
- fi
- if test -f 'ax25.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'ax25.c'\"
- else
- echo shar: Extracting \"'ax25.c'\" \(3577 characters\)
- sed "s/^X//" >'ax25.c' <<'END_OF_FILE'
- X#include <sys/types.h>
- X#include <sys/param.h>
- X#include <sys/socket.h>
- X#include <sys/stropts.h>
- X#include <sys/termios.h>
- X#include <sys/ttold.h>
- X#include <sys/sockio.h>
- X#include <sys/file.h>
- X#include <sys/if_ax.h>
- X#include <netinet/in.h>
- X#include <net/if.h>
- X#include <netinet/if_ether.h>
- X#include <stdio.h>
- X
- Xu_char ax25broadcastaddr[7] = {
- X 'Q'<<1, 'S'<<1, 'T'<<1, ' '<<1, ' '<<1, ' '<<1, '0'<<1
- X};
- Xstatic struct ether_addr etherbroadcastaddr = {
- X 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- X};
- X
- Xint
- Xmain(argc, argv)
- Xchar **argv;
- X{
- X struct termios tios;
- X u_char ax25[7];
- X struct ether_addr eth;
- X char cmd[128], name[64];
- X u_char *cp, c;
- X int verbose = 0;
- X int unit = 777;
- X int fd, i;
- X
- X if(argc<4) {
- X printf("usage: %s [-v] inet-addr ham-call-sign tty\n", *argv);
- X exit(0);
- X }
- X
- X if( !strcmp(argv[1], "-v") ) {
- X verbose = 1;
- X argv++;
- X }
- X
- X fd = open(argv[3], O_RDWR);
- X if(fd == -1) {
- X perror("open");
- X exit(1);
- X }
- X
- X while(1) {
- X if(verbose)
- X if(ioctl(fd, I_LOOK, name) != -1)
- X printf("popping module: %s\n", name);
- X if(ioctl(fd, I_POP, 0) == -1)
- X break;
- X }
- X
- X if( ioctl(fd, TCGETS, &tios) <0) {
- X perror("ioctl TCGETS");
- X exit(1);
- X }
- X
- X tios.c_cflag = CRTSCTS | B9600;
- X tios.c_cflag |= CS8|CREAD|HUPCL;
- X tios.c_iflag = IGNBRK;
- X if( ioctl(fd, TCSETS, &tios) <0) {
- X perror("ioctl TCSETS");
- X exit(1);
- X }
- X
- X if(verbose)
- X printf("pushing module: ax25\n");
- X if( ioctl(fd, I_PUSH, "ax25") == -1) {
- X perror("ioctl I_PUSH");
- X exit(1);
- X }
- X
- X if( ioctl(fd, AXIOGUNIT, &unit) != -1) {
- X if(verbose)
- X printf("network device: ax%d\n", unit);
- X } else {
- X perror("ioctl AXIOGUNIT");
- X exit(1);
- X }
- X
- X /*
- X * convert the HAM call sign to an ax25_addr
- X */
- X i = 0;
- X bzero((caddr_t)ax25, sizeof(ax25));
- X for(cp=(u_char *)argv[2]; *cp && (i<6); cp++) {
- X if(*cp=='-') {
- X cp++;
- X break;
- X }
- X c = islower(*cp) ? toupper(*cp) : *cp;
- X ax25[i++] = (u_char)(c << 1);
- X }
- X while(i<6)
- X ax25[i++] = (u_char)(' ' << 1);
- X while(*cp=='-')
- X cp++;
- X if(*cp)
- X ax25[6] = (u_char)(*cp << 1);
- X
- X ax_ax2ether(ax25, ð);
- X if( ioctl(fd, AXIOSHADDR, ð) == -1) {
- X perror("ioctl AXIOSHADDR");
- X exit(1);
- X }
- X
- X sprintf(cmd, "ifconfig ax%d %s netmask + broadcast + up",
- X unit, argv[1]);
- X if(verbose)
- X printf("execute: %s\n", cmd);
- X system(cmd);
- X
- X while(sigpause(0)!=-1)
- X ;
- X return 0;
- X}
- X
- X
- X/*
- X * convert an ax25 address to an ether_addr
- X */
- Xax_ax2ether(axhp, ethp)
- Xu_char *axhp;
- Xstruct ether_addr *ethp;
- X{
- X u_char c;
- X int i;
- X
- X printf("addresses: ax25 ");
- X for(i=0; i<6; i++)
- X printf("%02x.", axhp[i]);
- X printf("%02x '", axhp[6]);
- X
- X for(i=0; i<(7-1); i++)
- X printf("%c", axhp[i]>>1);
- X printf("-%c' = ether ", axhp[6]>>1);
- X
- X if( !bcmp((caddr_t)axhp, (caddr_t)ax25broadcastaddr,
- X sizeof(ax25broadcastaddr)) ) {
- X bcopy((caddr_t)ðerbroadcastaddr, (caddr_t)ethp,
- X sizeof(struct ether_addr));
- X goto done;
- X }
- X
- X ethp->ether_addr_octet[0] = 0x99;
- X c = ((((axhp[0]>>1) - ' ') << 2) & 0xfc);
- X c |= ((((axhp[1]>>1) - ' ') >> 4) & 0x03);
- X ethp->ether_addr_octet[1] = c;
- X c = ((((axhp[1]>>1) - ' ') << 4) & 0xf0);
- X c |= ((((axhp[2]>>1) - ' ') >> 2) & 0x0f);
- X ethp->ether_addr_octet[2] = c;
- X c = ((((axhp[2]>>1) - ' ') << 6) & 0xc0);
- X c |= ((((axhp[3]>>1) - ' ') ) & 0x3f);
- X ethp->ether_addr_octet[3] = c;
- X c = ((((axhp[4]>>1) - ' ') << 2) & 0xfc);
- X c |= ((((axhp[5]>>1) - ' ') >> 4) & 0x03);
- X ethp->ether_addr_octet[4] = c;
- X c = ((((axhp[5]>>1) - ' ') << 4) & 0xf0);
- X c |= ((((axhp[6]>>1) - '0') ) & 0x0f);
- X ethp->ether_addr_octet[5] = c;
- X
- Xdone:
- X for(i=0; i<sizeof(struct ether_addr)-1; i++)
- X printf("%02x:", ethp->ether_addr_octet[i]);
- X printf("%02x\n", ethp->ether_addr_octet[5]);
- X return 0;
- X}
- X
- END_OF_FILE
- if test 3577 -ne `wc -c <'ax25.c'`; then
- echo shar: \"'ax25.c'\" unpacked with wrong size!
- fi
- # end of 'ax25.c'
- fi
- if test -f 'ax25ether.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'ax25ether.c'\"
- else
- echo shar: Extracting \"'ax25ether.c'\" \(4192 characters\)
- sed "s/^X//" >'ax25ether.c' <<'END_OF_FILE'
- X#include <stdio.h>
- X#include <sys/types.h>
- X#include <sys/socket.h>
- X#include <netinet/in.h>
- X#include <net/if.h>
- X#include <netinet/if_ether.h>
- X#include <sys/if_ax.h>
- X
- Xu_char ax25broadcastaddr[7] = {
- X 'Q'<<1, 'S'<<1, 'T'<<1, ' '<<1, ' '<<1, ' '<<1, '0'<<1
- X};
- Xstatic struct ether_addr etherbroadcastaddr = {
- X 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- X};
- Xstatic struct ether_addr ethernulladdr;
- X
- X/*
- X * convert an ax25 address to an ether_addr
- X */
- Xax_ax2ether(axhp, ethp)
- Xu_char *axhp;
- Xstruct ether_addr *ethp;
- X{
- X u_char c;
- X int i;
- X
- X for(i=0; i<6; i++)
- X printf("%02x.", axhp[i]);
- X printf("%02x '", axhp[6]);
- X
- X for(i=0; i<(7-1); i++)
- X printf("%c", axhp[i]>>1);
- X printf("-%c' == ", axhp[6]>>1);
- X
- X if( !bcmp((caddr_t)axhp, (caddr_t)ax25broadcastaddr,
- X sizeof(ax25broadcastaddr)) ) {
- X bcopy((caddr_t)ðerbroadcastaddr, (caddr_t)ethp,
- X sizeof(struct ether_addr));
- X goto done;
- X }
- X
- X ethp->ether_addr_octet[0] = 0x99;
- X c = ((((axhp[0]>>1) - ' ') << 2) & 0xfc);
- X c |= ((((axhp[1]>>1) - ' ') >> 4) & 0x03);
- X ethp->ether_addr_octet[1] = c;
- X c = ((((axhp[1]>>1) - ' ') << 4) & 0xf0);
- X c |= ((((axhp[2]>>1) - ' ') >> 2) & 0x0f);
- X ethp->ether_addr_octet[2] = c;
- X c = ((((axhp[2]>>1) - ' ') << 6) & 0xc0);
- X c |= ((((axhp[3]>>1) - ' ') ) & 0x3f);
- X ethp->ether_addr_octet[3] = c;
- X c = ((((axhp[4]>>1) - ' ') << 2) & 0xfc);
- X c |= ((((axhp[5]>>1) - ' ') >> 4) & 0x03);
- X ethp->ether_addr_octet[4] = c;
- X c = ((((axhp[5]>>1) - ' ') << 4) & 0xf0);
- X c |= ((((axhp[6]>>1) - '0') ) & 0x0f);
- X ethp->ether_addr_octet[5] = c;
- X
- Xdone:
- X for(i=0; i<sizeof(struct ether_addr)-1; i++)
- X printf("%02x:", ethp->ether_addr_octet[i]);
- X printf("%02x\n", ethp->ether_addr_octet[5]);
- X return 0;
- X}
- X
- X/*
- X * convert an ether_addr to an ax25 address
- X */
- Xax_ether2ax(ethp, axhp)
- Xstruct ether_addr *ethp;
- Xu_char *axhp;
- X{
- X u_char c;
- X int i;
- X
- X for(i=0; i<sizeof(struct ether_addr)-1; i++)
- X printf("%02x:", ethp->ether_addr_octet[i]);
- X printf("%02x == ", ethp->ether_addr_octet[5]);
- X
- X if( !bcmp((caddr_t)ethp, (caddr_t)ðernulladdr,
- X sizeof(struct ether_addr))) {
- X printf("nothing\n");
- X return;
- X }
- X if( !bcmp((caddr_t)ethp, (caddr_t)ðerbroadcastaddr,
- X sizeof(struct ether_addr))) {
- X axhp[0] = 'Q' << 1;
- X axhp[1] = 'S' << 1;
- X axhp[2] = 'T' << 1;
- X axhp[3] = ' ' << 1;
- X axhp[4] = ' ' << 1;
- X axhp[5] = ' ' << 1;
- X axhp[6] = '0' << 1;
- X goto done;
- X }
- X
- X c = ethp->ether_addr_octet[0];
- X if(c != 0x99) {
- X printf("[NO MAPPING]\n");
- X for(i=0; i<7; i++)
- X axhp[i] = (i+1) << 1;
- X return;
- X }
- X c = (ethp->ether_addr_octet[1] >> 2) & 0x3f;
- X axhp[0] = (u_char)((c + ' ') << 1);
- X c = (ethp->ether_addr_octet[1] << 4) & 0x30;
- X c |= (ethp->ether_addr_octet[2] >> 4) & 0x0f;
- X axhp[1] = (u_char)((c + ' ') << 1);
- X c = (ethp->ether_addr_octet[2] << 2) & 0x3c;
- X c |= (ethp->ether_addr_octet[3] >> 6) & 0x03;
- X axhp[2] = (u_char)((c + ' ') << 1);
- X c = (ethp->ether_addr_octet[3] ) & 0x3f;
- X axhp[3] = (u_char)((c + ' ') << 1);
- X c = (ethp->ether_addr_octet[4] >> 2) & 0x3f;
- X axhp[4] = (u_char)((c + ' ') << 1);
- X c = (ethp->ether_addr_octet[4] << 4) & 0x30;
- X c |= (ethp->ether_addr_octet[5] >> 4) & 0x0f;
- X axhp[5] = (u_char)((c + ' ') << 1);
- X c = (ethp->ether_addr_octet[5] ) & 0x0f;
- X axhp[6] = (u_char)((c + '0') << 1);
- X
- Xdone:
- X for(i=0; i<6; i++)
- X printf("%02x.", axhp[i]);
- X printf("%02x '", axhp[6]);
- X
- X for(i=0; i<6; i++)
- X printf("%c", (axhp[i]>>1) & 0x7f );
- X printf("-%c'\n", (axhp[6]>>1) & 0x7f );
- X}
- X
- Xmain(argc, argv)
- Xchar **argv;
- X{
- X u_char ax25[7];
- X struct ether_addr eth;
- X u_char *cp, c;
- X int i;
- X
- X if(argc<3) {
- X fprintf(stderr, "usage: %s af addr\n", argv[0]);
- X fprintf(stderr, "\taf=ax25, ether\n");
- X exit(0);
- X }
- X
- X if( !strcmp(argv[1], "ax25")) {
- X i = 0;
- X bzero((caddr_t)ax25, sizeof(ax25));
- X for(cp=(u_char *)argv[2]; *cp && (i<6); cp++) {
- X if(*cp=='-') {
- X cp++;
- X break;
- X }
- X c = islower(*cp) ? toupper(*cp) : *cp;
- X ax25[i++] = (u_char)(c << 1);
- X }
- X while(i<6)
- X ax25[i++] = (u_char)(' ' << 1);
- X while(*cp=='-')
- X cp++;
- X if(*cp)
- X ax25[6] = (u_char)(*cp << 1);
- X ax_ax2ether(ax25, ð);
- X
- X } else if( !strcmp(argv[1], "ether")) {
- X bcopy((caddr_t)ether_aton(argv[2]), (caddr_t)ð,
- X sizeof(struct ether_addr));
- X ax_ether2ax(ð, ax25);
- X } else
- X printf("what?\n");
- X return 0;
- X}
- END_OF_FILE
- if test 4192 -ne `wc -c <'ax25ether.c'`; then
- echo shar: \"'ax25ether.c'\" unpacked with wrong size!
- fi
- # end of 'ax25ether.c'
- fi
- if test -f 'if_ax.h' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'if_ax.h'\"
- else
- echo shar: Extracting \"'if_ax.h'\" \(1890 characters\)
- sed "s/^X//" >'if_ax.h' <<'END_OF_FILE'
- X#ifndef _if_ax_h_
- X#define _if_ax_h_
- X
- X#define AXIOGUNIT _IOR(x, 111, int) /* get unit number */
- X#define AXIOSHADDR _IOW(x, 112, struct ether_addr) /* set ether_addr */
- X
- X#define AXSTREAMNAME "ax25" /* streams module name */
- X#define AXIFNAME "ax" /* interface name */
- X#define AX25MTU 1000 /* max ax25 packet size */
- X
- X/* An ax25 address is encoded as a struct ether_addr so that it can fit
- X * in the arp tables.
- X *
- X * encoding format in struct ether_addr
- X * ________ ______ ______ ______ ______ ______ ______ _____
- X * | 8 | 6 | 6 | 6 | 6 | 6 | 6 | 4 |
- X * |________|______|______|______|______|______|______|_____|
- X *
- X * The upper byte of ether_addr is set to 0x99.
- X *
- X * The next 6 6-bit fields are each filled with an ax25_addr.aa_c[] entry,
- X * shifted back to normal ASCII, and then offset from ASCII space
- X * (ie. aa_c[0] - ' ').
- X *
- X * The sid has values ASCII '0' -> ASCII '0'+15. ASCII '0' is subtraced and
- X * the low 4 bits of the ether_addr are set from that.
- X */
- X
- X/* screw digipeaters */
- Xstruct ax25_hdr {
- X u_char ah_dst[7], ah_src[7];
- X u_char ah_cmd;
- X u_char ah_pid;
- X};
- X
- X/*
- X * AX25 commands. All others are tossed.
- X */
- X#define AX25CMD_UI 0x03 /* AX25 datagram */
- X
- X/*
- X * AX25 Protocol IDs. All others are tossed.
- X */
- X#define AX25PID_IP 0xcc /* ARPA IP */
- X#define AX25PID_ARP 0xcd /* ARPA ARP */
- X
- X/*
- X * AX25 ARP address types.
- X */
- X#define AX25_HARDTYPE 0x0003
- X#define AX25_IPTYPE ((short)AX25PID_IP)
- X
- X/*
- X * KISS framing. This is SLIP.
- X */
- X#define KISS_END 0xc0
- X#define KISS_ESC 0xdb
- X#define KISS_TEND 0xdc
- X#define KISS_TESC 0xdd
- X
- X/*
- X * KISS commands - first data byte inside the KISS packet.
- X */
- X#define KISS_DATA 0x00
- X#define KISS_TXDELAY 0x01
- X#define KISS_PERSISTANCE 0x02
- X#define KISS_SLOTTIME 0x03
- X#define KISS_TXTAIL 0x04
- X#define KISS_FULLDUPLEX 0x05
- X#define KISS_HARDWARE 0x06
- X#define KISS_QUIT 0xff
- X
- X#endif /* _if_ax_h_ */
- END_OF_FILE
- if test 1890 -ne `wc -c <'if_ax.h'`; then
- echo shar: \"'if_ax.h'\" unpacked with wrong size!
- fi
- # end of 'if_ax.h'
- fi
- if test -f 'tty_ax.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'tty_ax.c'\"
- else
- echo shar: Extracting \"'tty_ax.c'\" \(23598 characters\)
- sed "s/^X//" >'tty_ax.c' <<'END_OF_FILE'
- X/*
- X * KISS+AX25 IP streams module for sunos 4.x
- X *
- X * Copyright 1991, 1992 by Theo de Raadt
- X *
- X * Theo de Raadt <deraadt@lego.cuc.ab.ca>
- X * Thanks to William Graham <uug@indigo.cuc.ab.ca> for AX25 specs.
- X *
- X * Streams ideas ripped off from PPP and SLIP implimentations for
- X * Sunos by Brad Clements and Rayan Zachariassen respectively.
- X */
- X#undef DEBUG
- X#undef DEBUG2
- X#define AX_NIT
- X
- X#include "ax.h"
- X#if NAX > 0
- X
- X#include <sys/types.h>
- X#include <sys/param.h>
- X#include <sys/stream.h>
- X#include <sys/stropts.h>
- X#include <sys/dir.h>
- X#include <sys/signal.h>
- X#include <sys/user.h>
- X#include <sys/mbuf.h>
- X#include <sys/socket.h>
- X#include <sys/sockio.h>
- X#include <sys/syslog.h>
- X
- X#include <netinet/in.h>
- X
- X#include <net/if.h>
- X#include <net/nit_if.h>
- X#include <netinet/if_ether.h>
- X#include <sys/if_ax.h>
- X
- X#include <net/netisr.h>
- X
- X#include <netinet/in_systm.h>
- X#include <netinet/in_var.h>
- X#include <netinet/ip.h>
- X
- X#ifdef AX_NIT
- Xstatic struct ether_header nitheader = { {{1}}, {{2}}, ETHERTYPE_IP };
- Xstatic struct nit_if nif = {(caddr_t)&nitheader, sizeof(nitheader), 0, 0};
- X
- Xstatic struct ether_header nitheader_arp = { {{1}}, {{2}}, ETHERTYPE_ARP };
- Xstatic struct nit_if nif_arp = {(caddr_t)&nitheader_arp, sizeof(nitheader_arp), 0, 0};
- X#endif
- X
- Xint ax_attach();
- Xstatic int ax_open(), ax_close(), ax_rput(), ax_wput(), ax_wsrv();
- Xstatic int ax_ioctl(), ax_output();
- Xstatic struct mbuf *ax_btom();
- X
- Xstatic struct module_info minfo = {
- X 0xabce, AXSTREAMNAME, 0, INFPSZ, 16384, 4096
- X};
- X
- Xstatic struct qinit r_init = {
- X ax_rput, NULL, ax_open, ax_close, NULL, &minfo, NULL
- X};
- X
- Xstatic struct qinit w_init = {
- X ax_wput, ax_wsrv, ax_open, ax_close, NULL, &minfo, NULL
- X};
- X
- Xstruct streamtab axinfo = {
- X &r_init, &w_init, NULL, NULL, NULL
- X};
- X
- Xstatic struct axpriv {
- X struct arpcom arpcom;
- X queue_t *q;
- X u_char *buf;
- X u_char *dp;
- X u_int inlen;
- X u_char gotesc, toobig;
- X} axpriv[NAX];
- X
- Xstatic u_char ax25broadcastaddr[7] = {
- X 'Q'<<1, 'S'<<1, 'T'<<1, ' '<<1, ' '<<1, ' '<<1, '0'<<1
- X};
- Xstatic struct ether_addr ethernulladdr;
- X
- Xint
- Xax_attach(unit)
- Xint unit;
- X{
- X register struct ifnet *ifp = &axpriv[unit].arpcom.ac_if;
- X
- X ifp->if_name = AXIFNAME;
- X ifp->if_mtu = AX25MTU;
- X ifp->if_flags = IFF_BROADCAST;
- X ifp->if_unit = unit;
- X ifp->if_ioctl = ax_ioctl;
- X ifp->if_output = ax_output;
- X ifp->if_snd.ifq_maxlen = IFQ_MAXLEN;
- X if_attach(ifp);
- X return 0;
- X}
- X
- Xstatic int
- Xax_open(q, dev, flag, sflag)
- Xqueue_t *q;
- Xdev_t dev;
- Xint flag, sflag;
- X{
- X struct axpriv *axp;
- X int unit, s;
- X
- X if( !suser()) {
- X u.u_error = EPERM;
- X return OPENFAIL;
- X }
- X
- X s = splstr();
- X for( unit=0; unit<NAX; ++unit) {
- X axp = &axpriv[unit];
- X
- X if(axp->buf)
- X continue;
- X if(axp->arpcom.ac_if.if_mtu == 0)
- X ax_attach(unit);
- X axp->arpcom.ac_if.if_flags |= IFF_RUNNING;
- X axp->buf = (u_char *)kmem_alloc(AX25MTU);
- X axp->dp = axp->buf + sizeof(struct ifnet *);
- X axp->inlen = 0;
- X axp->q = WR(q);
- X WR(q)->q_ptr = q->q_ptr = (caddr_t)axp;
- X (void) splx(s);
- X log(LOG_INFO, "ax%d: coming up\n", unit);
- X return unit;
- X }
- X splx(s);
- X log(LOG_INFO, "ax%d: no more devices available\n", NAX);
- X return OPENFAIL;
- X}
- X
- Xstatic int
- Xax_close(q, flag)
- Xqueue_t *q;
- Xint flag;
- X{
- X struct axpriv *axp;
- X int s;
- X
- X s = splimp();
- X axp = (struct axpriv *)q->q_ptr;
- X if(axp) {
- X log(LOG_INFO, "ax%d: going down\n", axp->arpcom.ac_if.if_unit);
- X if_down(&axp->arpcom.ac_if);
- X axp->arpcom.ac_if.if_flags &= ~(IFF_UP|IFF_RUNNING);
- X if(axp->buf)
- X kmem_free(axp->buf, AX25MTU);
- X axp->buf = NULL;
- X axp->q = NULL;
- X }
- X (void) splx(s);
- X}
- X
- Xstatic int
- Xax_wput(q, mp)
- Xqueue_t *q;
- Xmblk_t *mp;
- X{
- X struct axpriv *axp;
- X char ax25[7];
- X struct iocblk *iocp;
- X
- X switch(mp->b_datap->db_type) {
- X case M_FLUSH:
- X if(*mp->b_rptr & FLUSHW)
- X flushq(q, FLUSHDATA);
- X putnext(q, mp);
- X break;
- X case M_DATA:
- X putq(q, mp);
- X break;
- X case M_IOCTL:
- X iocp = (struct iocblk *)mp->b_rptr;
- X axp = (struct axpriv *)q->q_ptr;
- X switch(iocp->ioc_cmd) {
- X case AXIOSHADDR:
- X bcopy((caddr_t)mp->b_cont->b_rptr,
- X (caddr_t)&axp->arpcom.ac_enaddr,
- X sizeof(struct ether_addr));
- X mp->b_datap->db_type = M_IOCACK;
- X iocp->ioc_rval = iocp->ioc_count = iocp->ioc_error = 0;
- X qreply(q, mp);
- X log(LOG_INFO, "ax%d: ether %2x:%2x:%2x:%2x:%2x:%2x ax25 ",
- X axp->arpcom.ac_if.if_unit,
- X axp->arpcom.ac_enaddr.ether_addr_octet[0],
- X axp->arpcom.ac_enaddr.ether_addr_octet[1],
- X axp->arpcom.ac_enaddr.ether_addr_octet[2],
- X axp->arpcom.ac_enaddr.ether_addr_octet[3],
- X axp->arpcom.ac_enaddr.ether_addr_octet[4],
- X axp->arpcom.ac_enaddr.ether_addr_octet[5]);
- X ax_ether2ax(&axp->arpcom.ac_enaddr, ax25);
- X print_ax25addr(ax25);
- X printf("\n");
- X return;
- X case AXIOGUNIT:
- X iocp->ioc_rval = 0;
- X if( mp->b_cont = allocb(sizeof(int), BPRI_MED) ) {
- X u_char *cp = mp->b_cont->b_wptr;
- X
- X mp->b_datap->db_type = M_IOCACK;
- X *((int *)cp) = axp->arpcom.ac_if.if_unit;
- X mp->b_cont->b_wptr += sizeof(int);
- X iocp->ioc_count = sizeof(int);
- X iocp->ioc_error = 0;
- X qreply(q, mp);
- X break;
- X }
- X iocp->ioc_error = ENOSR;
- X mp->b_datap->db_type = M_IOCNAK;
- X qreply(q, mp);
- X return;
- X default:
- X log(LOG_INFO, "ax%d: unknown ioc %8x\n",
- X axp->arpcom.ac_if.if_unit, iocp->ioc_cmd);
- X putnext(q, mp);
- X return;
- X }
- X break;
- X default:
- X putnext(q, mp);
- X }
- X}
- X
- Xstatic int
- Xax_rput(q, mp)
- Xqueue_t *q;
- Xmblk_t *mp;
- X{
- X struct axpriv *axp = (struct axpriv *)q->q_ptr;
- X struct ifnet *ifp;
- X register u_char c, *rp;
- X register mblk_t *bp;
- X struct mbuf *m;
- X int proto, forus, s;
- X
- X if( axp==NULL ) {
- X log(LOG_INFO, "ax_rput: axp is NULL\n");
- X freemsg(mp);
- X return;
- X }
- X if( axp->buf==NULL ) {
- X log(LOG_INFO, "ax_rput: axp->buf is NULL\n");
- X freemsg(mp);
- X return;
- X }
- X
- X ifp = &axp->arpcom.ac_if;
- X switch(mp->b_datap->db_type) {
- X case M_DATA:
- X break;
- X case M_FLUSH:
- X if(*mp->b_rptr & FLUSHR)
- X flushq(q, FLUSHDATA);
- X putnext(q, mp);
- X return;
- X case M_UNHANGUP:
- X log(LOG_INFO, "ax%d: M_UNHANGUP\n", ifp->if_unit);
- X axp->q = WR(q); /* hook us up again */
- X putnext(q, mp);
- X putctl1(q->q_next, M_PCSIG, SIGURG);
- X return;
- X case M_HANGUP:
- X log(LOG_INFO, "ax%d: M_HANGUP\n", ifp->if_unit);
- X s = splstr();
- X axp->q = NULL; /* cause ax_output to return ENETDOWN */
- X (void) splx(s);
- X putnext(q, mp);
- X return;
- X case M_BREAK:
- X case M_IOCACK:
- X putnext(q, mp);
- X return;
- X default:
- X log(LOG_INFO, "ax%d: rput streams message type %d discarded\n",
- X ifp->if_unit, mp->b_datap->db_type);
- X putnext(q, mp);
- X return;
- X }
- X
- X /*
- X * Perform the KISS protocol on the streams message, and add the bytes
- X * to a packet reconstruction buffer. When a complete AX25 packet has
- X * been collected, strip the AX25 layer and provide the IP (or ARP) packet
- X * inside to the networking code.
- X */
- X for( bp=mp; bp; bp=bp->b_cont) {
- X rp = bp->b_rptr;
- X while( rp < bp->b_wptr) {
- X c = *rp++;
- X /*printf("K %2x\n", c);*/
- X if(axp->gotesc) {
- X axp->gotesc = 0;
- X if(c==KISS_TEND)
- X c = KISS_END;
- X else if(c==KISS_TESC)
- X c = KISS_ESC;
- X#ifdef DEBUG
- X else
- X log(LOG_INFO, "ax%d: kiss ESC error (c=%d)\n",
- X ifp->if_unit, c);
- X#endif
- X } else if(c==KISS_END) {
- X if(axp->toobig) {
- X axp->toobig = 0;
- X /*printf("ax%d: packet toobig\n",
- X ifp->if_unit);*/
- X axp->inlen = 0;
- X continue;
- X }
- X if(axp->inlen==0)
- X continue;
- X
- X /*
- X * buf contains KISS_DATA followed by an AX25
- X * packet. Extract the IP packet lurking inside
- X * AX25 packet..
- X */
- X m = ax_btom(axp, &proto, &forus);
- X axp->dp = axp->buf + sizeof(struct ifnet *);
- X ifp->if_ipackets++;
- X axp->inlen = 0;
- X if(!m) {
- X ifp->if_ierrors++;
- X continue;
- X }
- X
- X switch(proto) {
- X case AX25PID_IP:
- X#ifdef AX_NIT
- X if(ifp->if_flags & IFF_PROMISC) {
- X struct mbuf *nm = m;
- X int len = 0;
- X
- X do {
- X len += nm->m_len;
- X } while( nm=nm->m_next );
- X len -= sizeof(struct ifnet *);
- X m->m_off += sizeof(struct ifnet *);
- X nif.nif_bodylen = len;
- X snit_intr(&axp->arpcom, m, &nif);
- X m->m_off -= sizeof(struct ifnet *);
- X }
- X#endif
- X if(!forus) {
- X m_freem(m);
- X break;
- X }
- X s = splimp();
- X if( IF_QFULL(&ipintrq) ) {
- X IF_DROP(&ipintrq);
- X ifp->if_ierrors++;
- X m_freem(m);
- X (void) splx(s);
- X } else {
- X IF_ENQUEUE(&ipintrq, m);
- X schednetisr(NETISR_IP);
- X (void) splx(s);
- X#ifdef DEBUG
- X log(LOG_INFO, "handing off to IP\n");
- X#endif
- X }
- X break;
- X case AX25PID_ARP:
- X#ifdef AX_NIT
- X if(ifp->if_flags & IFF_PROMISC) {
- X struct mbuf *nm = m;
- X int len = 0;
- X
- X do {
- X len += nm->m_len;
- X } while( nm=nm->m_next );
- X len -= sizeof(struct ifnet *);
- X m->m_off += sizeof(struct ifnet *);
- X nif_arp.nif_bodylen = len;
- X snit_intr(&axp->arpcom, m, &nif_arp);
- X m->m_off -= sizeof(struct ifnet *);
- X }
- X#endif
- X if(!forus) {
- X m_freem(m);
- X break;
- X }
- X#ifdef DEBUG
- X printf("[INCOMING ethernet arp packet]");
- X ax25_arpdebug(m);
- X#endif
- X arpinput(&axp->arpcom, m);
- X break;
- X default:
- X#ifdef DEBUG2
- X printf("ax%d: unknown protocol %d\n",
- X ifp->if_unit,
- X proto);
- X#endif
- X m_freem(m);
- X break;
- X }
- X continue;
- X } else if(c==KISS_ESC) {
- X axp->gotesc = 1;
- X continue;
- X }
- X if(++axp->inlen > AX25MTU) {
- X if(axp->toobig)
- X continue;
- X axp->toobig = 1;
- X ifp->if_ierrors++;
- X axp->dp = axp->buf + sizeof(struct ifnet *);
- X continue;
- X } else
- X *axp->dp++ = c;
- X }
- X bp->b_rptr = rp;
- X }
- X freemsg(mp);
- X return;
- X}
- X
- X
- Xstatic struct mbuf *
- Xax_btom(axp, protop, forusp)
- Xstruct axpriv *axp;
- Xint *protop, *forusp;
- X{
- X struct ax25_hdr *ax;
- X struct mbuf *m, **mp, *top = NULL;
- X struct ifnet *ifp;
- X struct ether_addr oureth;
- X int len, count;
- X caddr_t cp;
- X
- X ax = (struct ax25_hdr *)(axp->buf + sizeof(struct ifnet *) + 1);
- X
- X /*
- X * digipeaters are not supported (they could be supported - could
- X * correct the AX25 packet's fields, KISS encode it, and send a
- X * message downstream to the TNC.)
- X *
- X * The IP packet must come in an AX25 UI frame.
- X */
- X if(ax->ah_cmd != AX25CMD_UI) {
- X#ifdef DEBUG2
- X printf("ax%d: ax25 frame not UI, cmd=%2x\n",
- X axp->arpcom.ac_if.if_unit, ax->ah_cmd);
- X#endif
- X return NULL;
- X }
- X
- X#ifdef DEBUG2
- X printf("ax%d: ", axp->arpcom.ac_if.if_unit);
- X print_ax25addr(ax->ah_src);
- X printf("->");
- X print_ax25addr(ax->ah_dst);
- X printf(" [%d]\n", axp->inlen - sizeof(struct ax25_hdr) - 1);
- X#endif
- X
- X /*
- X * is this packet to us?
- X */
- X *forusp = 1;
- X ax_ax2ether(ax->ah_dst, &oureth);
- X if( bcmp((caddr_t)&oureth, (caddr_t)&axp->arpcom.ac_enaddr,
- X sizeof oureth) &&
- X bcmp((caddr_t)ax25broadcastaddr, (caddr_t)&axp->arpcom.ac_enaddr,
- X sizeof oureth)) {
- X *forusp = 0;
- X }
- X
- X /*
- X * packet not for us, and not promisc mode --> can out.
- X */
- X if( !(axp->arpcom.ac_if.if_flags & IFF_PROMISC) && *forusp==0)
- X return NULL;
- X
- X /*
- X * check acceptable protocols
- X */
- X switch(ax->ah_pid) {
- X case AX25PID_IP:
- X case AX25PID_ARP:
- X break;
- X default:
- X#ifdef DEBUG2
- X printf("ax%d: packet discarded - protocol %d\n",
- X axp->arpcom.ac_if.if_unit, ax->ah_pid);
- X#endif
- X return NULL;
- X }
- X
- X *protop = (int)(ax->ah_pid);
- X ifp = &axp->arpcom.ac_if;
- X cp = (caddr_t)(axp->buf + sizeof(struct ifnet *) + 1 + sizeof(struct ax25_hdr));
- X mp = ⊤
- X len = axp->inlen - 1 - sizeof(struct ax25_hdr);
- X while(len>0) {
- X MGET(m, M_DONTWAIT, MT_DATA);
- X if(m == NULL) {
- X if(top)
- X m_freem(top);
- X return NULL;
- X }
- X *mp = m;
- X if(ifp) {
- X m->m_off += sizeof(ifp);
- X count = MIN(len, MLEN - sizeof(ifp));
- X bcopy(cp, mtod(m, caddr_t), count);
- X m->m_len = count;
- X m->m_off -= sizeof(ifp);
- X m->m_len += sizeof(ifp);
- X *mtod(m, struct ifnet **) = ifp;
- X ifp = NULL;
- X } else {
- X count = MIN(len, MLEN);
- X bcopy(cp, mtod(m, caddr_t), count);
- X m->m_len = count;
- X }
- X cp += count;
- X len -= count;
- X mp = &m->m_next;
- X }
- X if(ax->ah_pid== AX25PID_ARP) {
- X top->m_off += sizeof(ifp); /* XXX ax_ax2etherarp() weak */
- X ax_ax2etherarp(top);
- X top->m_off -= sizeof(ifp);
- X }
- X
- X return top;
- X}
- X
- X
- Xstatic int
- Xax_wsrv(q)
- Xqueue_t *q;
- X{
- X register mblk_t *mp;
- X
- X while( mp=getq(q) ) {
- X if( !canput(q->q_next)) {
- X putbq(q, mp);
- X return;
- X }
- X putnext(q, mp);
- X }
- X}
- X
- X/* %%% ifconfig ether #:#:#:#:#:# not working */
- Xstatic int
- Xax_ioctl(ifp, cmd, data)
- Xstruct ifnet *ifp;
- Xint cmd;
- Xcaddr_t data;
- X{
- X register struct ifaddr *ifa = (struct ifaddr *)data;
- X register struct ifreq *ifr = (struct ifreq *)data;
- X int error = 0, s;
- X
- X if(ifa==NULL)
- X return EFAULT;
- X s = splimp();
- X switch(cmd) {
- X case SIOCSIFFLAGS:
- X if(!data) /* IFF_PROMISC change */
- X break;
- X if(!suser()) {
- X error = EPERM;
- X break;
- X }
- X ifp->if_flags &= IFF_CANTCHANGE;
- X ifp->if_flags |= (ifr->ifr_flags & ~IFF_CANTCHANGE);
- X break;
- X case SIOCGIFFLAGS:
- X ifr->ifr_flags = ifp->if_flags;
- X break;
- X case SIOCSIFADDR:
- X switch(ifa->ifa_addr.sa_family) {
- X case AF_INET:
- X ((struct arpcom *)ifp)->ac_ipaddr = IA_SIN(ifa)->sin_addr;
- X ifp->if_flags |= IFF_UP;
- X break;
- X default:
- X error = EAFNOSUPPORT;
- X break;
- X }
- X break;
- X case SIOCSIFBRDADDR:
- X if(ifa->ifa_addr.sa_family != AF_INET)
- X error = EAFNOSUPPORT;
- X break;
- X case SIOCSIFNETMASK:
- X if(ifa->ifa_addr.sa_family != AF_INET)
- X error = EAFNOSUPPORT;
- X break;
- X default:
- X error = EINVAL;
- X }
- X (void) splx(s);
- X return error;
- X}
- X
- Xstatic int
- Xax_output(ifp, m0, dst)
- Xstruct ifnet *ifp;
- Xstruct mbuf *m0;
- Xstruct sockaddr *dst;
- X{
- X struct axpriv *axp;
- X struct ax25_hdr ax25;
- X struct ether_header *eth;
- X struct mbuf *m = m0;
- X int i, len, s, n;
- X struct in_addr idst;
- X u_char *cp, *cp2;
- X mblk_t *mp;
- X
- X axp = &axpriv[ifp->if_unit];
- X if(axp->q == NULL)
- X return ENETDOWN;
- X
- X /* printf("ax%d: trying to send packet\n", ifp->if_unit); */
- X
- X switch(dst->sa_family) {
- X case AF_INET:
- X#ifdef AX_NIT
- X if(axp->arpcom.ac_if.if_flags & IFF_PROMISC) {
- X struct mbuf *nm = m0;
- X int len = 0;
- X
- X do {
- X len += nm->m_len;
- X } while( nm=nm->m_next );
- X nif.nif_bodylen = len;
- X snit_intr(&axp->arpcom, m0, &nif);
- X }
- X
- X#endif
- X idst = ((struct sockaddr_in *)dst)->sin_addr;
- X ((struct arpcom *)ifp)->ac_lastip = idst;
- X m = m0;
- X if( !arpresolve((struct arpcom *)ifp, m)) {
- X return 0;
- X }
- X#ifdef DEBUG2
- X len = 0;
- X for(m=m0; m; m=m->m_next) {
- X cp = mtod(m, u_char *);
- X n = m->m_len;
- X while(n-->0) {
- X if( !(len++ % 16) )
- X printf("\n\t");
- X printf("%2x ", *cp++);
- X }
- X }
- X if( len % 16 )
- X printf("\n");
- X#endif
- X ax25.ah_pid = AX25PID_IP;
- X ax_ether2ax(&((struct arpcom *)ifp)->ac_enaddr, ax25.ah_src);
- X ax_ether2ax(&((struct arpcom *)ifp)->ac_lastarp, ax25.ah_dst);
- X#ifdef DEBUG2
- X printf("ax%d: sending to ", ifp->if_unit);
- X print_ax25addr(ax25.ah_dst);
- X printf("\n");
- X#endif
- X break;
- X case AF_UNSPEC:
- X eth = (struct ether_header *)dst->sa_data;
- X switch(eth->ether_type) {
- X case ETHERTYPE_ARP:
- X case ETHERTYPE_REVARP:
- X#ifdef AX_NIT
- X if(axp->arpcom.ac_if.if_flags & IFF_PROMISC) {
- X struct mbuf *nm = m0;
- X int len = 0;
- X
- X do {
- X len += nm->m_len;
- X } while( nm=nm->m_next );
- X nif_arp.nif_bodylen = len;
- X snit_intr(&axp->arpcom, m0, &nif_arp);
- X }
- X
- X#endif
- X#ifdef DEBUG2
- X printf("AF_UNSPEC: ARP\n");
- X printf("[ethernet arp packet]");
- X len = 0;
- X for(m=m0; m; m=m->m_next) {
- X cp = mtod(m, u_char *);
- X n = m->m_len;
- X while(n-->0) {
- X if( !(len++ % 16) )
- X printf("\n\t");
- X printf("%2x ", *cp++);
- X }
- X }
- X if( len % 16 )
- X printf("\n");
- X#endif
- X
- X ax_ether2axarp(m0);
- X ax25.ah_pid = AX25PID_ARP;
- X ax_ether2ax(&((struct arpcom *)ifp)->ac_enaddr, ax25.ah_src);
- X ax_ether2ax(ð->ether_dhost, ax25.ah_dst);
- X#ifdef DEBUG2
- X printf("[AX25 arp packet]");
- X#endif
- X break;
- X default:
- X printf("AF_UNSPEC: unknown ether_type %4x",
- X ntohs(eth->ether_type));
- X ax25.ah_pid = AX25PID_IP; /* wrong */
- X ax_ether2ax(ð->ether_shost, ax25.ah_src);
- X ax_ether2ax(ð->ether_dhost, ax25.ah_dst);
- X break;
- X }
- X
- X#ifdef DEBUG2
- X len = 0;
- X for(m=m0; m; m=m->m_next) {
- X cp = mtod(m, u_char *);
- X n = m->m_len;
- X while(n-->0) {
- X if( !(len++ % 16) )
- X printf("\n\t");
- X printf("%2x ", *cp++);
- X }
- X }
- X if( len % 16 )
- X printf("\n");
- X#endif
- X
- X break;
- X default:
- X log(LOG_INFO, "ax%d: cannot handle af%d\n", ifp->if_unit,
- X dst->sa_family);
- X m_freem(m0);
- X return EAFNOSUPPORT;
- X }
- X
- X ax25.ah_cmd = AX25CMD_UI;
- X ax25.ah_src[6] |= 0x01; /* %%% set low bit on src */
- X
- X /*
- X * run through the ax25_hdr and the packet buffer counting
- X * how much space we need for KISS encoding.
- X */
- X len = 2; /* KISS_END, KISS_DATA */
- X for(i=0, cp=(u_char *)&ax25; i< sizeof(ax25); i++, cp++) {
- X len++;
- X if(*cp==KISS_END || *cp==KISS_ESC)
- X len++;
- X }
- X for(m=m0; m; m=m->m_next) {
- X cp = mtod(m, u_char *);
- X for(i=0; i< m->m_len; i++, cp++) {
- X len++;
- X if(*cp==KISS_END || *cp==KISS_ESC)
- X len++;
- X }
- X }
- X len++; /* KISS_END */
- X
- X if( !(mp = allocb(len, BPRI_MED)) ) {
- X log(LOG_INFO, "ax%d: ax_output cannot allocb %d bytes\n",
- X ifp->if_unit, len);
- X m_freem(m0);
- X return ENOSR;
- X }
- X
- X#ifdef DEBUG2
- X cp2 = mp->b_wptr;
- X#endif
- X
- X /*
- X * KISS-format the ax25 header and data into mp.
- X */
- X *mp->b_wptr++ = KISS_END;
- X *mp->b_wptr++ = KISS_DATA;
- X for(i=0, cp=(u_char *)&ax25; i<sizeof(ax25); i++, cp++) {
- X switch(*cp) {
- X case KISS_END:
- X *mp->b_wptr++ = KISS_ESC;
- X *mp->b_wptr++ = KISS_TEND;
- X break;
- X case KISS_ESC:
- X *mp->b_wptr++ = KISS_ESC;
- X *mp->b_wptr++ = KISS_TESC;
- X break;
- X default:
- X *mp->b_wptr++ = *cp;
- X break;
- X }
- X }
- X for(m=m0; m; m=m->m_next) {
- X cp = mtod(m, u_char *);
- X for(i=0; i< m->m_len; i++, cp++) {
- X switch(*cp) {
- X case KISS_END:
- X *mp->b_wptr++ = KISS_ESC;
- X *mp->b_wptr++ = KISS_TEND;
- X break;
- X case KISS_ESC:
- X *mp->b_wptr++ = KISS_ESC;
- X *mp->b_wptr++ = KISS_TESC;
- X break;
- X default:
- X *mp->b_wptr++ = *cp;
- X break;
- X }
- X }
- X }
- X *mp->b_wptr++ = KISS_END; /* superfluous, really */
- X
- X#ifdef DEBUG2
- X printf("actual serial output:\n");
- X while(cp2 < mp->b_wptr)
- X printf("%2x ", *cp2++);
- X printf("\n");
- X#endif
- X
- X s = splstr();
- X if(axp->q)
- X putq(axp->q, mp);
- X else
- X freemsg(mp);
- X (void) splx(s);
- X m_freem(m0);
- X return 0;
- X}
- X
- X/*
- X * convert an ethernet ARP packet to an AX25 ARP packet. The AX25 frame
- X * header is not included.
- X */
- Xax_ether2axarp(m)
- Xstruct mbuf *m;
- X{
- X struct arphdr *arp = mtod(m, struct arphdr *);
- X struct ether_addr eth1, eth2;
- X struct in_addr in1, in2;
- X caddr_t cp;
- X
- X arp->ar_hrd = AX25_HARDTYPE;
- X arp->ar_pro = AX25_IPTYPE;
- X arp->ar_hln = 7;
- X
- X cp = ((caddr_t)arp) + sizeof(struct arphdr);
- X bcopy(cp, (caddr_t)ð1, sizeof(struct ether_addr));
- X cp += sizeof(struct ether_addr);
- X bcopy(cp, (caddr_t)&in1, sizeof(struct in_addr));
- X cp += sizeof(struct in_addr);
- X bcopy(cp, (caddr_t)ð2, sizeof(struct ether_addr));
- X cp += sizeof(struct ether_addr);
- X bcopy(cp, (caddr_t)&in2, sizeof(struct in_addr));
- X
- X cp = ((caddr_t)arp) + sizeof(struct arphdr);
- X ax_ether2ax(ð1, (u_char *)cp);
- X cp += 7;
- X bcopy((caddr_t)&in1, cp, sizeof(struct in_addr));
- X cp += sizeof(struct in_addr);
- X ax_ether2ax(ð2, (u_char *)cp);
- X cp += 7;
- X bcopy((caddr_t)&in2, cp, sizeof(struct in_addr));
- X
- X m->m_len += 2;
- X return 0;
- X}
- X
- X/*
- X * convert an AX25 ARP packet to an ethernet ARP packet. The AX25 frame
- X * is assumed to have been already stripped off.
- X */
- Xax_ax2etherarp(m)
- Xstruct mbuf *m;
- X{
- X struct arphdr *arp = mtod(m, struct arphdr *);
- X u_char axa1[7], axa2[7];
- X struct in_addr in1, in2;
- X caddr_t cp;
- X
- X#ifdef DEBUG2
- X printf("[INCOMING AX25 arp packet]");
- X ax25_arpdebug(m);
- X#endif
- X
- X arp->ar_hrd = ARPHRD_ETHER;
- X arp->ar_pro = ETHERTYPE_IP;
- X arp->ar_hln = sizeof(struct ether_addr);
- X
- X cp = ((caddr_t)arp) + sizeof(struct arphdr);
- X bcopy(cp, (caddr_t)axa1, 7);
- X cp += 7;
- X bcopy(cp, (caddr_t)&in1, sizeof(struct in_addr));
- X cp += sizeof(struct in_addr);
- X bcopy(cp, (caddr_t)axa2, 7);
- X cp += 7;
- X bcopy(cp, (caddr_t)&in2, sizeof(struct in_addr));
- X
- X cp = ((caddr_t)arp) + sizeof(struct arphdr);
- X ax_ax2ether(axa1, (struct ether_addr *)cp);
- X cp += sizeof(struct ether_addr);
- X bcopy((caddr_t)&in1, cp, sizeof(struct in_addr));
- X cp += sizeof(struct in_addr);
- X ax_ax2ether(axa2, (struct ether_addr *)cp);
- X cp += sizeof(struct ether_addr);
- X bcopy((caddr_t)&in2, cp, sizeof(struct in_addr));
- X
- X m->m_len -= 2;
- X return 0;
- X}
- X
- X/*
- X * convert an ax25_addr to an ether_addr
- X */
- Xax_ax2ether(axhp, ethp)
- Xu_char *axhp;
- Xstruct ether_addr *ethp;
- X{
- X u_char c;
- X int i;
- X
- X#ifdef DEBUG2
- X for(i=0; i<6; i++)
- X printf("%2x.", axhp[i]);
- X printf("%2x '", axhp[6]);
- X
- X for(i=0; i<(7-1); i++)
- X printf("%c", (axhp[i]>>1) & 0x7f );
- X printf("-%c' == ", (axhp[6]&0x7f)>>1 & 0x7f );
- X#endif
- X
- X if( !bcmp((caddr_t)axhp, (caddr_t)ax25broadcastaddr,
- X sizeof(ax25broadcastaddr)) ) {
- X bcopy((caddr_t)ðerbroadcastaddr, (caddr_t)ethp,
- X sizeof(struct ether_addr));
- X goto done;
- X }
- X
- X ethp->ether_addr_octet[0] = 0x99;
- X c = ((((axhp[0]>>1) - ' ') << 2) & 0xfc);
- X c |= ((((axhp[1]>>1) - ' ') >> 4) & 0x03);
- X ethp->ether_addr_octet[1] = c;
- X c = ((((axhp[1]>>1) - ' ') << 4) & 0xf0);
- X c |= ((((axhp[2]>>1) - ' ') >> 2) & 0x0f);
- X ethp->ether_addr_octet[2] = c;
- X c = ((((axhp[2]>>1) - ' ') << 6) & 0xc0);
- X c |= ((((axhp[3]>>1) - ' ') ) & 0x3f);
- X ethp->ether_addr_octet[3] = c;
- X c = ((((axhp[4]>>1) - ' ') << 2) & 0xfc);
- X c |= ((((axhp[5]>>1) - ' ') >> 4) & 0x03);
- X ethp->ether_addr_octet[4] = c;
- X c = ((((axhp[5]>>1) - ' ') << 4) & 0xf0);
- X c |= (((((axhp[6]&0x7f)>>1) - '0') ) & 0x0f);
- X ethp->ether_addr_octet[5] = c;
- X
- Xdone:
- X#ifdef DEBUG2
- X for(i=0; i<sizeof(struct ether_addr)-1; i++)
- X printf("%2x:", ethp->ether_addr_octet[i]);
- X printf("%2x\n", ethp->ether_addr_octet[5]);
- X#endif
- X return 0;
- X}
- X
- X/*
- X * convert an ether_addr to an ax25_addr
- X */
- Xax_ether2ax(ethp, axhp)
- Xstruct ether_addr *ethp;
- Xu_char *axhp;
- X{
- X u_char c;
- X int i;
- X
- X#ifdef DEBUG2
- X for(i=0; i<sizeof(struct ether_addr)-1; i++)
- X printf("%2x:", ethp->ether_addr_octet[i]);
- X printf("%2x == ", ethp->ether_addr_octet[5]);
- X#endif
- X
- X if( !bcmp((caddr_t)ethp, (caddr_t)ðernulladdr,
- X sizeof(struct ether_addr))) {
- X#ifdef DEBUG2
- X printf("nothing\n");
- X#endif
- X for(i=0; i<7; i++)
- X axhp[i] = (u_char)0;
- X return;
- X }
- X if( !bcmp((caddr_t)ethp, (caddr_t)ðerbroadcastaddr,
- X sizeof(struct ether_addr))) {
- X bcopy((caddr_t)ax25broadcastaddr, (caddr_t)axhp,
- X sizeof(ax25broadcastaddr));
- X goto done;
- X }
- X c = ethp->ether_addr_octet[0];
- X if(c != 0x99) {
- X#ifdef DEBUG2
- X printf("[NO MAPPING]\n");
- X#endif
- X for(i=0; i<7; i++)
- X axhp[i] = (u_char)0;
- X return;
- X }
- X c = (ethp->ether_addr_octet[1] >> 2) & 0x3f;
- X axhp[0] = (u_char)((c + ' ') << 1);
- X c = (ethp->ether_addr_octet[1] << 4) & 0x30;
- X c |= (ethp->ether_addr_octet[2] >> 4) & 0x0f;
- X axhp[1] = (u_char)((c + ' ') << 1);
- X c = (ethp->ether_addr_octet[2] << 2) & 0x3c;
- X c |= (ethp->ether_addr_octet[3] >> 6) & 0x03;
- X axhp[2] = (u_char)((c + ' ') << 1);
- X c = (ethp->ether_addr_octet[3] ) & 0x3f;
- X axhp[3] = (u_char)((c + ' ') << 1);
- X c = (ethp->ether_addr_octet[4] >> 2) & 0x3f;
- X axhp[4] = (u_char)((c + ' ') << 1);
- X c = (ethp->ether_addr_octet[4] << 4) & 0x30;
- X c |= (ethp->ether_addr_octet[5] >> 4) & 0x0f;
- X axhp[5] = (u_char)((c + ' ') << 1);
- X c = (ethp->ether_addr_octet[5] ) & 0x0f;
- X axhp[6] = (u_char)((c + '0') << 1);
- X
- Xdone:
- X#ifdef DEBUG2
- X for(i=0; i<6; i++)
- X printf("%2x.", axhp[i]);
- X printf("%2x '", axhp[6]);
- X
- X for(i=0; i<6; i++)
- X printf("%c", (axhp[i] >> 1) & 0x7f );
- X printf("-%c'\n", ((axhp[6] & 0x7f) >> 1) & 0x7f );
- X#endif
- X return;
- X}
- X
- Xprint_ax25addr(axhp)
- Xu_char *axhp;
- X{
- X int i;
- X
- X#ifdef DEBUG2
- X for(i=0; i<6; i++)
- X printf("%2x.", axhp[i]);
- X printf("%2x", axhp[6]);
- X#endif
- X
- X printf("(");
- X for(i=0; i<6; i++)
- X printf("%c", (axhp[i]>>1) & 0x7f );
- X printf("-%c)", ((axhp[6]&0x7f)>>1) & 0x7f );
- X}
- X
- Xax25_arpdebug(m0)
- Xstruct mbuf *m0;
- X{
- X struct mbuf *m;
- X int len, n;
- X u_char *cp;
- X
- X len = 0;
- X for(m=m0; m; m=m->m_next) {
- X printf("*");
- X cp = mtod(m, u_char *);
- X n = m->m_len;
- X while(n-->0) {
- X if( !(len++ % 16) )
- X printf("\n\t");
- X printf("%2x ", *cp++);
- X }
- X }
- X if( len % 16 )
- X printf("\n");
- X}
- X
- X
- X#endif /* !(NAX > 0) */
- X
- END_OF_FILE
- if test 23598 -ne `wc -c <'tty_ax.c'`; then
- echo shar: \"'tty_ax.c'\" unpacked with wrong size!
- fi
- # end of 'tty_ax.c'
- fi
- echo shar: End of shell archive.
- exit 0
-